#include "cc9d.h"
#include "crc8.h"

static const byte SEPARATOR = 0x9d;//分隔符
static const byte ESCAPE = 0x9e;//转义字符
static const byte ESC_9D = 0xfe;//9D转义目标
static const byte ESC_9E = 0xff;//9E转义目标 

// 	发送相关的程序
static void sendByte(byte b);
void cc9d_SendPkg(sCc9dPkg pkg_mem_type* pkg, uint8 data_len){
	byte pkg_mem_type* buf;
	uint8 i;
	byte send_crc;	
	buf = (byte pkg_mem_type*)pkg;
	send_crc = 0xff;	
	for(i=0; i < data_len+4; i++){
		sendByte(buf[i]);
		crcInput(send_crc, buf[i]);
	}
	sendByte(send_crc);
	_cc9d_sendByte(SEPARATOR);
}

static void sendByte(byte b) {
	if (b == SEPARATOR) {
		_cc9d_sendByte(ESCAPE);
		_cc9d_sendByte(ESC_9D);
	} else if (b == ESCAPE) {
		_cc9d_sendByte(ESCAPE);
		_cc9d_sendByte(ESC_9E);
	} else {
		_cc9d_sendByte(b);
	}
}
	



// 	接收相关的程序	
static byte pkg_mem_type* recv_buf;
static byte last_Byte;//用于接收最后一字节，既最大包时的CRC。
static int8 recv_ptr = 0;
static void recvData(byte b) {
	if (recv_ptr < sizeof(sCc9dPkg)){//数据收入缓冲区
		recv_buf[recv_ptr] = b;
		recv_ptr++;
	}
	else if (recv_ptr == sizeof(sCc9dPkg)){//数据收入最后一个字节
		last_Byte = b;
		recv_ptr++;
	}else{//收到数据太长了，在遇到停止符之前，不再接收。
		recv_ptr = sizeof(sCc9dPkg)+2;
	}
}
static void recvEnd() {
	uint8 i,pkg_crc;
	byte recv_crc = 0xff;
	sCc9dPkg pkg_mem_type* next_buf = (sCc9dPkg pkg_mem_type* )recv_buf;
	if ((recv_ptr >=5 )&&(recv_ptr < sizeof(sCc9dPkg) + 1)) {//包长度正常
		pkg_crc = recv_buf[recv_ptr - 1]; 
	} else if (recv_ptr == sizeof(sCc9dPkg) + 1) {//极限长度包
		pkg_crc = last_Byte;
	} else {//长度不正常
		goto finished;
	}
	
	for(i=0; i<recv_ptr-1; i++){
		crcInput(recv_crc,recv_buf[i]);		
	}
	if (recv_crc != pkg_crc) {//crc 错误
		goto finished;		
	}
	next_buf = _cc9d_receivePkg((sCc9dPkg pkg_mem_type*)recv_buf, recv_ptr - 5);
	if (next_buf != 0) {
		recv_buf = (byte pkg_mem_type*)next_buf;
	}
finished:
	//继续收下一个包
	recv_ptr = 0;
	return;
}

static void recvEsc(byte b) {//收到转义命令
	//斥候模块不需要转义命令，这里为空。	
}		

#define YES 1
#define NO 0
static uint8 is_in_esc = NO;
void cc9d_recvbyte(byte b) {
	if (is_in_esc==YES) {
		is_in_esc = NO;
		if (b >= 0xfe) {
			recvData((byte)(b - (ESC_9D - SEPARATOR)));//b is fe => 9D ;b is ff => 9E
		} else {
			recvEsc(b);
		}
	} else {
		if (b == SEPARATOR) {
			recvEnd();
		} else if (b == ESCAPE) {
			is_in_esc = YES;
		} else {
			recvData(b);
		}
	}
}
void cc9d_init(sCc9dPkg pkg_mem_type* pkg){
	recv_buf = (byte pkg_mem_type*)pkg;
	recv_ptr = 0;	
	is_in_esc = NO;
	_cc9d_sendByte(SEPARATOR);
	_cc9d_sendByte(SEPARATOR);
}	


